
#import "JMIotUtils.h"
#import "JMCommonUtils.h"

#import <SystemConfiguration/SystemConfiguration.h>
#import <netinet/in.h>
#import <CommonCrypto/CommonDigest.h>
#import <objc/runtime.h>

#import <IMSApiClient/IMSApiClient.h>
#import <IMSAuthentication/IMSAuthentication.h>
#import <AlinkAppExpress/LKAppExpress.h>
#import <IMSAccount/IMSAccount.h>

#import "FFLoading.h"
#import "Masonry.h"

#import "Definition.h"

@implementation JMIotUtils

#pragma mark -

// 登出
+ (void)logOut {
    NSString *topic = @"/account/unbind";
    [[LKAppExpress sharedInstance] invokeWithTopic:topic
                                              opts:nil
                                            params:@{}
                                       respHandler:^(LKAppExpResponse *_Nonnull response) {
                                         if (![response successed]) {
                                             NSLog(@"解绑长连接推送失败");
                                         } else {
                                             NSLog(@"解绑长连接推送成功");
                                         }
                                       }];
    [[IMSAccountService sharedService] logout];
}

#pragma mark - 虚拟设备

// 创建虚拟设备
+ (void)createVirtualDeviceWithProductKey:(NSString *)key completionHandler:(void (^)(NSError *error, NSDictionary *info))completionHandler {
    NSString *path = @"/thing/virtual/register";
    NSString *version = @"1.0.0";
    NSDictionary *params = @{
        @"productKey" : key ?: @"",
    };
    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 绑定虚拟设备
+ (void)bindVirtualDeviceWithKey:(NSString *)key deviceName:(NSString *)name completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/thing/virtual/binduser";
    NSString *version = @"1.0.0";
    NSDictionary *params = @{
        @"productKey" : key ?: @"",
        @"deviceName" : name ?: @"",
    };
    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 获取用户绑定的虚拟设备列表
+ (void)loadVirtualDeviceListWithCompletionHandler:(void (^)(NSError *error, NSArray *list))completionHandler {
    /**
    //有时候有效,有时候无效
    NSString *path = @"/uc/listBindingByAccount";
    NSString *version = @"1.0.8";
    NSDictionary *params = @{
        @"thingType" : @"VIRTUAL",
    };
    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id result) {
        if (completionHandler) {
            completionHandler(error, result[@"data"]);
        }
    }];
     */

    [JMIotUtils loadAllDeviceListWithCompletionHandler:^(NSError *error, NSArray *list) {
      NSMutableArray *virtualList = [NSMutableArray array];
      for (NSDictionary *info in list) {
          NSString *type = info[@"thingType"];
          if ([type isEqualToString:@"VIRTUAL"] || [type isEqualToString:@"VIRTUAL_SHADOW"]) {
              [virtualList addObject:info];
          }
      }

      if (completionHandler) {
          completionHandler(error, virtualList);
      }
    }];
}

#pragma mark - 真实设备

// 获取产品信息
+ (void)queryProductInfoWithIotID:(NSString *)iotId completionHandler:(void (^)(NSError *error, NSDictionary *info))completionHandler {
    NSString *path = @"/thing/detailInfo/queryProductInfo";
    NSString *version = @"1.1.4";
    NSDictionary *params = @{
        @"iotId" : iotId ?: @"",
    };
    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 获取产品productKey
+ (void)queryProductKeyWithProductId:(NSString *)productId completionHandler:(void (^)(NSError *error, NSDictionary *info))completionHandler {
    NSString *path = @"/thing/productInfo/queryProductKey";
    NSString *version = @"1.1.4";
    NSDictionary *params = @{
        @"productId" : productId ?: @"",
    };
    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 获取用户绑定的设备列表
+ (void)loadDeviceListWithCompletionHandler:(void (^)(NSError *error, NSArray *list))completionHandler {
    NSString *path = @"/uc/listBindingByAccount";
    NSString *version = @"1.0.8";
    NSDictionary *params = @{
        @"thingType" : @"DEVICE",
    };
    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id result) {
                                 if (completionHandler) {
                                     completionHandler(error, result[@"data"]);
                                 }
                               }];
}

// 获取用户所有绑定的设备列表(包含真实设备,虚拟设备,虚拟影子设备等)
+ (void)loadAllDeviceListWithCompletionHandler:(void (^)(NSError *error, NSArray *list))completionHandler {
    NSString *path = @"/uc/listBindingByAccount";
    NSString *version = @"1.0.8";
    NSDictionary *params = @{};
    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id result) {
                                 if (completionHandler) {
                                     completionHandler(error, result[@"data"]);
                                 }
                               }];
}

// 获取设备发现列表
+ (void)getAllDeviceListWithCompletionHandler:(void (^)(NSError *error, NSArray *list))completionHandler {
    NSString *path = @"/awss/enrollee/list/get";
    NSString *version = @"1.0.7";
    NSDictionary *params = @{@"pageSize" : @(100), @"pageNum" : @(1)};
    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 获取支持配网的产品列表
+ (void)getProductListWithCompletionHandler:(void (^)(NSError *error, NSArray *list))completionHandler {
    NSString *path = @"/thing/productInfo/getByAppKey";
    NSString *apiVersion = @"1.1.7";

    NSDictionary *dic = @{};

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:apiVersion
                                          params:dic
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 获取物的属性
+ (void)getDevicePropertiesWithIotId:(NSString *)iotId completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/thing/properties/get";
    NSString *apiVersion = @"1.0.4";

    NSDictionary *dic = @{@"iotId" : iotId};

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:apiVersion
                                          params:dic
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 设置物的属性
+ (void)setDevicePropertiesWithIotId:(NSString *)iotId params:(NSDictionary *)params completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/thing/properties/set";
    NSString *apiVersion = @"1.0.5";
    NSDictionary *dic = @{@"iotId" : iotId, @"items" : params};

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:apiVersion
                                          params:dic
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 获取物的连接状态
+ (void)getDeviceStatusWithIotId:(NSString *)iotId completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/thing/status/get";
    NSString *apiVersion = @"1.0.4";
    NSDictionary *dic = @{@"iotId" : iotId};

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:apiVersion
                                          params:dic
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 设置设备昵称
+ (void)setDeviceNickName:(NSString *)name withIotID:(NSString *)iotId completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/uc/setDeviceNickName";
    NSString *apiVersion = @"1.0.6";
    NSDictionary *dic = @{@"iotId" : iotId, @"nickName" : name};

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:apiVersion
                                          params:dic
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 绑定WIFI设备(设备通过WIFI方式进行通讯)
+ (void)bindWifiDeviceWithProductKey:(NSString *)key deviceName:(NSString *)name token:(NSString *)token completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/awss/token/user/bind";
    NSString *version = @"1.0.8";
    NSDictionary *params = @{
        @"productKey" : key ?: @"",
        @"deviceName" : name ?: @"",
        @"token" : token ?: @"",
    };
    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 绑定GPRS设备(设备通过GPRS方式进行通讯)
+ (void)bindGPRSDeviceWithProductKey:(NSString *)key deviceName:(NSString *)name completionHandler:(void (^)(NSError *error, NSString *iotId))completionHandler {
    NSString *path = @"/awss/gprs/user/bind";
    NSString *version = @"1.0.2";
    NSDictionary *params = @{
        @"productKey" : key ?: @"",
        @"deviceName" : name ?: @"",
    };
    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 解绑用户和设备
+ (void)unbindWifiDeviceWithIotId:(NSString *)iotId completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/uc/unbindAccountAndDev";
    NSString *apiVersion = @"1.0.9";
    NSDictionary *dic = @{@"iotId" : iotId ?: @""};

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:apiVersion
                                          params:dic
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 解除分享/管理员解绑设备
+ (void)unbindByManagerWithIotIds:(NSArray *)iotIdList withIdentityId:(NSString *)targetIdentityId completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/uc/unbindByManager";
    NSString *apiVersion = @"1.0.6";
    NSDictionary *dic = @{@"targetIdentityId" : targetIdentityId ?: @"", @"iotIdList" : iotIdList};

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:apiVersion
                                          params:dic
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

#pragma mark - push

// 关联移动推送到某账号。当账号登录时，App会自动关联移动推送到当前账号。
+ (void)bindAPNSChannelWithDeviceId:(NSString *)deviceId completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/uc/bindPushChannel";
    NSString *version = @"1.0.6";
    NSDictionary *params = @{
        @"deviceId" : deviceId ?: @"",
        @"deviceType" : @"iOS"
    };

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 取消关联移动推送到某账号。当账号登出时，App会自动取消关联移动推送到当前账号。
+ (void)unbindAPNSChannelWithDeviceId:(NSString *)deviceId completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/uc/unbindPushChannel";
    NSString *version = @"1.0.6";
    NSDictionary *params = @{
        @"deviceId" : deviceId ?: @"",
    };

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

#pragma mark -

// 生成分线的二维码
+ (void)generateShareQrCode:(NSArray *)iotIds completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/uc/generateShareQrCode";
    NSString *version = @"1.0.7";
    NSDictionary *params = @{@"iotIdList" : iotIds, @"sceneIdList" : @[]};

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 通过二维码绑定设备
+ (void)scanBindShareQrCode:(NSString *)qrKey completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/uc/scanBindByShareQrCode";
    NSString *version = @"1.0.8";
    NSDictionary *params = @{@"qrKey" : qrKey};

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 根据设备获取绑定关系
+ (void)listBindingByDev:(NSString *)iotId completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/uc/listBindingByDev";
    NSString *version = @"1.0.6";
    NSDictionary *params = @{@"iotId" : iotId};

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

// 设备分享给指定的用户
+ (void)shareDevicesAndScenes:(NSArray *)iotIdList target:(NSString *)identityId completionHandler:(void (^)(NSError *error, id data))completionHandler {
    NSString *path = @"/uc/shareDevicesAndScenes";
    NSString *version = @"1.0.8";
    NSDictionary *params = @{@"iotIdList" : iotIdList, @"targetIdentityId" : identityId};

    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

+ (void)requestWithPath:(NSString *)path version:(NSString *)version params:(NSDictionary *)params completionHandler:(void (^)(NSError *error, id data))completionHandler {
    [[JMIotUtils sharedInstance] requestWithPath:path
                                         version:version
                                          params:params
                               completionHandler:^(NSError *error, id data) {
                                 if (completionHandler) {
                                     completionHandler(error, data);
                                 }
                               }];
}

#pragma mark -

- (void)dealloc {
}

+ (JMIotUtils *)sharedInstance {
    static JMIotUtils *Instance;
    @synchronized(Instance) {
        if (!Instance) {
            Instance = [[JMIotUtils alloc] init];
        }
    }
    return Instance;
}

- (id)init {
    self = [super init];
    if (self) {
    }
    return self;
}

- (void)requestWithPath:(NSString *)path version:(NSString *)version params:(NSDictionary *)params completionHandler:(void (^)(NSError *error, id data))completionHandler {
    //
    if (![JMCommonUtils isNetworkReachable]) {
        [FFLoading showAutomicHiddenHudText:@"网络异常，请检查网络连接"];
        if (completionHandler) {
            NSDictionary *info = @{
                @"message" : @"网络异常，请检查网络连接",
                NSLocalizedDescriptionKey : @"网络异常，请检查网络连接",
            };
            NSError *err = [NSError errorWithDomain:@"" code:0 userInfo:info];
            completionHandler(err, nil);
        }
        return;
    }
    //
    IMSIoTRequestBuilder *builder = [[IMSIoTRequestBuilder alloc] initWithPath:path apiVersion:version params:params];
    IMSRequest *request = [[builder setAuthenticationType:IMSAuthenticationTypeIoT] build];

    [IMSRequestClient asyncSendRequest:request
                       responseHandler:^(NSError *error, IMSResponse *response) {
                         dispatch_async(dispatch_get_main_queue(), ^{
                           if (error) {
                               if (completionHandler) {
                                   completionHandler(error, response.data);
                               }
                           } else {
                               if (response.code != 200) {
                                   if (response.code == 401 || response.code == 1005) {
                                       [FFLoading showAutomicHiddenHudText:@"您的账号在另外一台手机登录,请重新登录"];
#define ACCOUNT_FORCE_LOGOUT @"AcountForceLogout"
                                       [[NSNotificationCenter defaultCenter] postNotificationName:ACCOUNT_FORCE_LOGOUT
                                                                                           object:nil];
                                   }

                                   if (completionHandler) {
                                       NSDictionary *info = @{
                                           @"message" : response.message ?: @"",
                                           NSLocalizedDescriptionKey : response.localizedMsg ?: @"",
                                       };
                                       NSError *err = [NSError errorWithDomain:@"" code:response.code userInfo:info];
                                       completionHandler(err, response.data);
                                   }
                               } else {
                                   if (completionHandler) {
                                       completionHandler(error, response.data);
                                   }
                               }
                           }
                         });
                       }];
}

@end
